{
 "cells": [
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# MFE 230P: ASSIGNMENT II\n",
    "**YOUR STUDENT ID** \\\\ YOUR NAME \\\\ YOUR GROUP NAME"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# 1. Factor Modeling\n",
    "\n",
    "Suppose we have obtained a covariance matrix $\\Sigma \\in \\mathbb{R}^{p \\times p}$. We seek to approximate it with a factor model of the form $\\hat{\\Sigma} = \\lambda \\mathbb{I}_p + FF^\\top$, where $F$ is a $p \\times k$ matrix, or \"factor loadings,\" $\\lambda>0$ is the \"idiosyncratic noise\" variance, and $\\mathbb{I}_p$ a $p \\times p$ identity matrix. The stochastic model that corresponds to this is\n",
    "\n",
    "$$y = Ff + \\sigma e$$\n",
    "\n",
    "where $y \\in \\mathbb{R}^p$ is a (random) vector of centered observations, $f\n",
    "\\in \\mathbb{R}^{k}$ is a random variable with zero mean and $e \\in\n",
    "\\mathbb{R}^p$ is a noise vector with identity covariance matrix, $\\sigma =\n",
    "\\sqrt{\\lambda}$ is the standard deviation of the idiosyncratic noise component\n",
    "$\\sigma e$. To approximate $F,\\lambda$, we seek to solve\n",
    "\n",
    "$$\\min_{F,\\lambda} \\: \\left\\|\\Sigma - \\lambda I_p - FF^\\top\\right\\|_F \\text{ subject to } \\lambda>0$$\n",
    "\n",
    "where $\\|\\cdot\\|_F$ stands for the Frobenius norm of its matrix argument. In\n",
    "this exercise, we develop an EVD-based solution to this problem."
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### A. Regularized Covariance Approximation\n",
    "\n",
    "Assume $\\lambda$ is known and less than $\\lambda_k$ (the $k^{th}$ largest\n",
    "eigenvalue of the covariance matrix $\\Sigma$). Express the eigenvalues\n",
    "of $\\Sigma - \\lambda \\mathbb{I}_p$ in terms of the eigenvalues of $\\Sigma$. Use your\n",
    "result to express an optimal $F$ as a function of $\\lambda$, which we'll denote\n",
    "$F(\\lambda)$. (In other words: you are asked to solve for $F$, with fixed\n",
    "$\\lambda$.)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### SOLUTION.\n",
    "\n",
    "_Your solution here._"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### B. Analyzing the Residual Covariance\n",
    "\n",
    "Show that the error $E(\\lambda) = \\left\\|\\Sigma - \\lambda \\mathbb{I}_p -\n",
    "F(\\lambda)F(\\lambda)^\\top\\right\\|_F$, with $F(\\lambda)$ being the matrix you found in the\n",
    "previous part, can be written as\n",
    "\n",
    "$$E(\\lambda)^2 = \\sum_{i=k+1}^p (\\lambda_i - \\lambda)^2$$\n",
    "\n",
    "Find a closed-form expression for the optimal $\\lambda$ that minimizes\n",
    "$E(\\lambda)$. (Express optimal $\\lambda$ in terms of $\\lambda_i$.) "
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### SOLUTION.\n",
    "\n",
    "_Your solution here._"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### C. Low-Rank Covariance Approximation\n",
    "\n",
    "Another way to approximate the covariance matrix $\\Sigma$ is through\n",
    "low-rank approximation. A rank-$k$ approximation to $\\Sigma$ is of the form\n",
    "$\\tilde{\\Sigma} = FF^\\top$. Assume that we wish to estimate the risk (as measured\n",
    "by variance) involved in a specific portfolio, which is described by a $x \\in\n",
    "\\mathbb{R}^p$. Show that compared to using the original $\\Sigma$, the\n",
    "rank-$k$ approximation $\\tilde{\\Sigma}$ under-estimates the variance of the\n",
    "portfolio. How about using the regularized factor model $\\hat{\\Sigma}$? Briefly\n",
    "comment."
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### SOLUTION.\n",
    "\n",
    "_Your solution here._"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# 2. Generalized Low-Rank Models"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### A. PCA and Convexity\n",
    "\n",
    "**True or False:** _The pca problem_\n",
    "\n",
    "$$\\min_{Z} \\|A - Z\\|^2_F \\text{ subject to } \\mathbf{rank}(Z) \\leq k$$\n",
    "\n",
    "\n",
    "\n",
    "_is a convex optimization problem, where $0 < k < \\min\\{m,n\\}$._ Justify your answer."
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### SOLUTION.\n",
    "\n",
    "_Your solution here._"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### B. Nuclear Norm Denoising\n",
    "\n",
    "Recall that, for any symmetric positive definite matrix $A \\in \\mathbb{R}^{n\\times n}$,\n",
    "\n",
    "$$P \\begin{bmatrix}\n",
    "\\mathbb{I}_k & \\mathbf{0} \\\\\n",
    "\\mathbf{0} & \\mathbf{0}\n",
    "\\end{bmatrix}\n",
    "D P^\\top = \\arg\\min_{Z} \\frac{1}{2}\\|A - Z\\|^2_F \\text{ subject to } \\mathbf{rank}(Z) \\leq k$$\n",
    "\n",
    "where $0 < k < n$, $A = PD P^\\top$ via EVD, and $\\mathbb{I}_k$ is the $k\\times k$ identity matrix. Practitioners (such as those at Netflix) often work with a close, \"relaxed\" version of the above problem known as **Nuclear Norm Denoising**:\n",
    "\n",
    "$$\\min_{Z} \\frac{1}{2} \\|A - Z\\|^2_F + \\lambda\\|Z\\|_*$$\n",
    "\n",
    "in which $\\lambda > 0$ serves a similar purpose to $k$ in the former problem. \n",
    "\n",
    "Express the solution to the nuclear norm denoising problem in closed form. **Hint:** Both the Forbenius norm $\\|\\cdot\\|_F$ and the nuclear norm $\\|\\cdot\\|_*$ are invariant to orthogonal rotation. Furthermore, for $\\lambda >0$,\n",
    "\n",
    "$$(y - \\lambda)_+ = \\arg\\min_x \\frac{(y - x)^2}{2} + \\lambda |x|$$\n",
    "\n",
    "where $x$ and $y$ are scalars."
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### SOLUTION.\n",
    "\n",
    "_Your solution here._"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### C. Robust PCA and Convexity\n",
    "\n",
    "**True or False:** _The robust pca problem_\n",
    "\n",
    "$$\\min_{Z, S} \\|Z\\|_* + \\lambda\\|S\\|_1 \\text{ subject to } A = Z + S$$\n",
    "\n",
    "_is a convex optimization problem, where $\\lambda > 0$._ Justify your answer."
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### SOLUTION.\n",
    "\n",
    "_Your solution here._"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### D. Robust PCA as a Generalized Low-Rank Model\n",
    "\n",
    "Recall from lecture that a **generalized low-rank model** is defined by the problem\n",
    "\n",
    "$$\\min_{X,Y} \\mathcal{L}\\left(X, Y\\right) + \\ell_x\\left(X\\right) + \\ell_y\\left(Y\\right)$$\n",
    "\n",
    "where $\\mathcal{L}$ is bi-convex in $(X, Y)$ and $\\ell$ is convex. Show that robust PCA can be formulated as a generalized low-rank model. _**Hint:** For any matrix $Z = XY^\\top$, $\\|Z\\|_* = \\frac{1}{2}\\left( \\|X\\|^2_F + \\|Y\\|^2_F\\right)$._"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### SOLUTION.\n",
    "\n",
    "_Your solution here._"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### E. Robust PCA Implemenetation\n",
    "\n",
    "Write a `Python` implementation of robust PCA using the template provided in the following cell. The output of the function `robustPCA` should be both $Z$ and $S$ from problem C above.\n",
    "\n",
    "You may not use any external packages with the exception of `cvxpy` and `numpy`."
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### SOLUTION.\n",
    "\n",
    "_Your solution here._"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### F. A Robust Factor Model\n",
    "\n",
    "Practitioners and academics alike often hypothesize that market returns are driven by a small number of [latent factors](http://www.investopedia.com/terms/m/multifactor-model.asp) and that any asset's deviation from the market's performance is idiosyncratic; due perhaps to something that isn't related to the factors or the greater economy. Our goal in this exercise is to decompose returns into a latent, low-rank component $Z$ and a sparse \"shocks\" component $S$ using robust PCA.\n",
    "\n",
    "Executing the next cell below will download a dataset containing two years (2014-15) of daily adjusted returns for 16 of the largest tech firms by market cap; firms that characterize the tech sector. The returns data will be stored in a variable `data`, a pandas dataframe object, in which the column headers are company tickers and the row index is the date.\n",
    "\n",
    "Perform robust PCA on the daily returns for $\\lambda \\in \\{.5, .25, .1\\}$. For each choice of $\\lambda$, plot the raw returns of the 16 companies as a line chart (top), the low-rank approximation of the 16 companies as a line chart (middle), and the sparse component of the 16 companies as a bar chart (bottom). In each figure, the horizontal axis should represent date while the vertical axis should represent daily returns. What is the _approximate_ $\\mathbf{rank}(Z)$ for each choice of $\\lambda$ (you will need to count the number of singular values that are `1e-6` the size or less of the largest singular value)? How can this be interpreted? Which choice of $\\lambda$ produces results that best align with your economic intuitition (this is a subjective question)?"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 2,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/html": [
       "<div>\n",
       "<table border=\"1\" class=\"dataframe\">\n",
       "  <thead>\n",
       "    <tr style=\"text-align: right;\">\n",
       "      <th></th>\n",
       "      <th>GOOGL</th>\n",
       "      <th>MSFT</th>\n",
       "      <th>FB</th>\n",
       "      <th>ORCL</th>\n",
       "      <th>INTC</th>\n",
       "      <th>CSCO</th>\n",
       "      <th>IBM</th>\n",
       "      <th>QCOM</th>\n",
       "      <th>TXN</th>\n",
       "      <th>AVGO</th>\n",
       "      <th>NVDA</th>\n",
       "      <th>ADBE</th>\n",
       "      <th>CRM</th>\n",
       "      <th>ADP</th>\n",
       "      <th>ITW</th>\n",
       "      <th>YHOO</th>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>date</th>\n",
       "      <th></th>\n",
       "      <th></th>\n",
       "      <th></th>\n",
       "      <th></th>\n",
       "      <th></th>\n",
       "      <th></th>\n",
       "      <th></th>\n",
       "      <th></th>\n",
       "      <th></th>\n",
       "      <th></th>\n",
       "      <th></th>\n",
       "      <th></th>\n",
       "      <th></th>\n",
       "      <th></th>\n",
       "      <th></th>\n",
       "      <th></th>\n",
       "    </tr>\n",
       "  </thead>\n",
       "  <tbody>\n",
       "    <tr>\n",
       "      <th>2014-01-02</th>\n",
       "      <td>-0.006772</td>\n",
       "      <td>-0.006683</td>\n",
       "      <td>0.001116</td>\n",
       "      <td>-0.010977</td>\n",
       "      <td>-0.006357</td>\n",
       "      <td>-0.019171</td>\n",
       "      <td>-0.010876</td>\n",
       "      <td>-0.012525</td>\n",
       "      <td>-0.018447</td>\n",
       "      <td>-0.004331</td>\n",
       "      <td>-0.009988</td>\n",
       "      <td>-0.009837</td>\n",
       "      <td>-0.005979</td>\n",
       "      <td>-0.011621</td>\n",
       "      <td>-0.010585</td>\n",
       "      <td>-0.021019</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>2014-01-03</th>\n",
       "      <td>-0.007295</td>\n",
       "      <td>-0.006728</td>\n",
       "      <td>-0.002797</td>\n",
       "      <td>-0.005814</td>\n",
       "      <td>-0.000388</td>\n",
       "      <td>-0.000909</td>\n",
       "      <td>0.005983</td>\n",
       "      <td>-0.005865</td>\n",
       "      <td>0.004408</td>\n",
       "      <td>0.003799</td>\n",
       "      <td>-0.011980</td>\n",
       "      <td>-0.002193</td>\n",
       "      <td>0.004739</td>\n",
       "      <td>0.010894</td>\n",
       "      <td>0.006611</td>\n",
       "      <td>0.013387</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>2014-01-06</th>\n",
       "      <td>0.011149</td>\n",
       "      <td>-0.021132</td>\n",
       "      <td>0.048445</td>\n",
       "      <td>-0.003987</td>\n",
       "      <td>-0.012413</td>\n",
       "      <td>0.001365</td>\n",
       "      <td>-0.003429</td>\n",
       "      <td>-0.002607</td>\n",
       "      <td>-0.008316</td>\n",
       "      <td>-0.006812</td>\n",
       "      <td>0.013401</td>\n",
       "      <td>-0.017579</td>\n",
       "      <td>-0.016147</td>\n",
       "      <td>-0.011396</td>\n",
       "      <td>-0.012300</td>\n",
       "      <td>-0.004736</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>2014-01-07</th>\n",
       "      <td>0.019276</td>\n",
       "      <td>0.007750</td>\n",
       "      <td>0.012587</td>\n",
       "      <td>0.010141</td>\n",
       "      <td>0.004910</td>\n",
       "      <td>0.013630</td>\n",
       "      <td>0.019946</td>\n",
       "      <td>0.007428</td>\n",
       "      <td>-0.005358</td>\n",
       "      <td>0.009602</td>\n",
       "      <td>0.016373</td>\n",
       "      <td>0.014625</td>\n",
       "      <td>0.013277</td>\n",
       "      <td>0.012154</td>\n",
       "      <td>-0.001330</td>\n",
       "      <td>0.024793</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>2014-01-08</th>\n",
       "      <td>0.002083</td>\n",
       "      <td>-0.017852</td>\n",
       "      <td>0.005352</td>\n",
       "      <td>-0.003435</td>\n",
       "      <td>-0.006058</td>\n",
       "      <td>-0.000762</td>\n",
       "      <td>-0.009172</td>\n",
       "      <td>0.006008</td>\n",
       "      <td>0.013817</td>\n",
       "      <td>0.014832</td>\n",
       "      <td>0.013631</td>\n",
       "      <td>-0.001187</td>\n",
       "      <td>0.036215</td>\n",
       "      <td>-0.005323</td>\n",
       "      <td>-0.006538</td>\n",
       "      <td>0.002444</td>\n",
       "    </tr>\n",
       "  </tbody>\n",
       "</table>\n",
       "</div>"
      ],
      "text/plain": [
       "               GOOGL      MSFT        FB      ORCL      INTC      CSCO  \\\n",
       "date                                                                     \n",
       "2014-01-02 -0.006772 -0.006683  0.001116 -0.010977 -0.006357 -0.019171   \n",
       "2014-01-03 -0.007295 -0.006728 -0.002797 -0.005814 -0.000388 -0.000909   \n",
       "2014-01-06  0.011149 -0.021132  0.048445 -0.003987 -0.012413  0.001365   \n",
       "2014-01-07  0.019276  0.007750  0.012587  0.010141  0.004910  0.013630   \n",
       "2014-01-08  0.002083 -0.017852  0.005352 -0.003435 -0.006058 -0.000762   \n",
       "\n",
       "                 IBM      QCOM       TXN      AVGO      NVDA      ADBE  \\\n",
       "date                                                                     \n",
       "2014-01-02 -0.010876 -0.012525 -0.018447 -0.004331 -0.009988 -0.009837   \n",
       "2014-01-03  0.005983 -0.005865  0.004408  0.003799 -0.011980 -0.002193   \n",
       "2014-01-06 -0.003429 -0.002607 -0.008316 -0.006812  0.013401 -0.017579   \n",
       "2014-01-07  0.019946  0.007428 -0.005358  0.009602  0.016373  0.014625   \n",
       "2014-01-08 -0.009172  0.006008  0.013817  0.014832  0.013631 -0.001187   \n",
       "\n",
       "                 CRM       ADP       ITW      YHOO  \n",
       "date                                                \n",
       "2014-01-02 -0.005979 -0.011621 -0.010585 -0.021019  \n",
       "2014-01-03  0.004739  0.010894  0.006611  0.013387  \n",
       "2014-01-06 -0.016147 -0.011396 -0.012300 -0.004736  \n",
       "2014-01-07  0.013277  0.012154 -0.001330  0.024793  \n",
       "2014-01-08  0.036215 -0.005323 -0.006538  0.002444  "
      ]
     },
     "execution_count": 2,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "import pandas as pd\n",
    "\n",
    "data = pd.read_csv(\n",
    "    '../../data/big_16_tech_returns.csv',\n",
    "    header=0,\n",
    "    index_col=0\n",
    ")\n",
    "\n",
    "data.index = pd.to_datetime(data.index, format='%Y%m%d')\n",
    "\n",
    "data.head()"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### SOLUTION.\n",
    "\n",
    "_Your solution here._"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### G. Interpreting the Results\n",
    "\n",
    "How can you interpret the decomposition obatined via robust PCA in terms of idiosyncratic and systematic risk, specifically in the context of the tech sector? Do some additional research on the largest few shocks in the sparse component $S$; what happened those days?"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### SOLUTION.\n",
    "\n",
    "_Your solution here._"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# 3. Matrix Completion\n",
    "\n",
    "In asset pricing and economics, it's common to obtain statistical quantities, such as covariance, via [structural equations and modeling](https://en.wikipedia.org/wiki/Structural_estimation). (This is to be compared with [reduced-form estimation](https://en.wikipedia.org/wiki/Reduced_form), in which statistical quantities are typically obtained directly by solving a system of equations.) As such, there are instances in which a set of structural equations is intractable due to unobservable quantities or limitations on the availability of data.\n",
    "\n",
    "In this exercise, we will use matrix completion to fill in the missing entries of a partially-observed asset covariance matrix obtained via structural estimation."
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### A. Exact Matrix Completion\n",
    "\n",
    "The array `Sigma` below denotes the partially-observed covariance matrix of five assets' returns."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "collapsed": true
   },
   "outputs": [],
   "source": [
    "Sigma = np.array(\n",
    "      [[  453.,   -36.,    -2.,np.nan, np.nan],\n",
    "       [  -36., np.nan, np.nan,   20.,    96.],\n",
    "       [   -2., np.nan,   105.,np.nan,    63.],\n",
    "       [np.nan,    20., np.nan,  131.,   119.],\n",
    "       [np.nan,    96.,    63.,  119., np.nan]]\n",
    ")"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Fill in the missing entries using the [original matrix completion algorithm](https://en.wikipedia.org/wiki/Matrix_completion#Convex_relaxation) and `print` the solution. What is the approximate rank of the completed matrix? What does this say about the assets?"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### SOLUTION.\n",
    "\n",
    "_Your solution here._"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### B. Matrix Completion with Uncertainty Bounds\n",
    "\n",
    "In practice, even the observed entries of the covariance `Sigma` may not be known exactly. Instead of filling in the missing entries exactly, consider solving the problem\n",
    "\n",
    "$$\\min_{\\hat{\\Sigma}} \\left\\|\\hat{\\Sigma}\\right\\|_* \\text{ subject to } \\forall (i,j) \\in \\Omega: \\Sigma^{(L)}_{ij} \\leq \\hat{\\Sigma}_{ij} \\leq \\Sigma^{(U)}_{ij}$$\n",
    "\n",
    "where $\\Omega$ is the set of indices corresponding to observed entries of $\\Sigma$ and $\\left(\\Sigma^{(L)}_{ij}, \\Sigma^{(U)}_{ij}\\right)$ can be taken as a non-empty confidence set for $\\Sigma_{ij}$. We will refer to this problem generally as _matrix completion with uncertainty bounds_.\n",
    "\n",
    "Show that for a fixed $\\Sigma$, the minimum (i.e. the nuclear norm of the solution) of matrix completion with uncertainty bounds is upper-bounded by the minimum of the exact matrix completion problem. Next, provided below are arrays `Sigma_L` and `Sigma_U` characterizing lower and upper bounds on the observed entries of $\\Sigma$."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "collapsed": true
   },
   "outputs": [],
   "source": [
    "Sigma_L = np.array(\n",
    "      [[  45.3,  -54. ,   -3. , np.nan, np.nan],\n",
    "       [ -54. , np.nan, np.nan,    2. ,    9.6],\n",
    "       [  -3. , np.nan,   10.5, np.nan,    6.3],\n",
    "       [np.nan,    2. , np.nan,   13.1,   11.9],\n",
    "       [np.nan,    9.6,    6.3,   11.9, np.nan]]\n",
    ")\n",
    "\n",
    "Sigma_U = np.array(\n",
    "      [[ 498.,   -4.,     -0.,np.nan,np.nan],\n",
    "       [  -4., np.nan, np.nan,   22.,  106.],\n",
    "       [  -0., np.nan,   116.,np.nan,   69.],\n",
    "       [np.nan,   22., np.nan,  144.,  131.],\n",
    "       [np.nan,  106.,    69.,  131.,np.nan]]\n",
    ")"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Fill in the missing entries by solveing the matrix completion with uncertainty bounds problem. What is the rank of completed matrix? How does this compare to part A?"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### SOLUTION.\n",
    "\n",
    "_Your solution here._"
   ]
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": "Python 3",
   "language": "python",
   "name": "python3"
  },
  "language_info": {
   "codemirror_mode": {
    "name": "ipython",
    "version": 3
   },
   "file_extension": ".py",
   "mimetype": "text/x-python",
   "name": "python",
   "nbconvert_exporter": "python",
   "pygments_lexer": "ipython3",
   "version": "3.5.3"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 2
}
